<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>高抛抛物线动画</title>
  <style>
    body {
      font-family: 'Arial', sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      margin: 0;
      overflow: hidden;
    }

    .container {
      position: relative;
      width: 100%;
      height: 80vh;
      max-width: 1000px;
      margin-top: 20px;
      border: 2px dashed rgba(0, 0, 0, 0.1);
    }

    .item {
      width: 60px;
      height: 60px;
      background: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 100%);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
      position: absolute;
      transition: transform 0.2s;
    }

    .target {
      width: 80px;
      height: 80px;
      background: linear-gradient(45deg, #a18cd1 0%, #fbc2eb 100%);
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 24px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
      position: absolute;
      right: 20px;
      bottom: 20px;
    }

    .flying-item {
      position: absolute;
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 100%);
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 12px;
      z-index: 100;
      pointer-events: none;
      will-change: transform;
    }

    .controls {
      margin-top: 20px;
      display: flex;
      gap: 15px;
    }

    button {
      padding: 12px 24px;
      background: linear-gradient(45deg, #4facfe 0%, #00f2fe 100%);
      border: none;
      border-radius: 30px;
      color: white;
      font-weight: bold;
      cursor: pointer;
      box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
      transition: all 0.3s;
    }

    button:hover {
      transform: translateY(-3px);
      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
    }

    .height-control {
      display: flex;
      align-items: center;
      gap: 10px;
    }

    input[type="range"] {
      width: 200px;
    }
  </style>
</head>

<body>
  <h1>高抛抛物线动画演示</h1>
  <div class="container" id="container">
    <div class="item" id="item1" style="left: 100px; top: 400px;">16</div>
    <div class="item" id="item2" style="left: 200px; top: 300px;">26</div>
    <div class="item" id="item3" style="left: 300px; top: 200px;">36</div>
    <div class="target" id="target">目标</div>
  </div>

  <div class="controls">
    <button id="resetBtn">重置动画</button>
    <button id="randomBtn">随机位置</button>
    <div class="height-control">
      <span>抛射高度:</span>
      <input type="range" id="heightSlider" min="100" max="500" value="300">
      <span id="heightValue">300px</span>
    </div>
  </div>

  <script>
    document.addEventListener('DOMContentLoaded', function () {
      const container = document.getElementById('container');
      const items = document.querySelectorAll('.item');
      const target = document.getElementById('target');
      const resetBtn = document.getElementById('resetBtn');
      const randomBtn = document.getElementById('randomBtn');
      const heightSlider = document.getElementById('heightSlider');
      const heightValue = document.getElementById('heightValue');

      let parabolaHeight = 300;

      // 更新高度显示
      heightSlider.addEventListener('input', function () {
        parabolaHeight = parseInt(this.value);
        heightValue.textContent = `${parabolaHeight}px`;
      });

      // 为每个物品添加点击事件
      items.forEach(item => {
        item.addEventListener('click', function () {
          createParabolaAnimation(this, target);
        });
      });

      // 重置按钮
      resetBtn.addEventListener('click', function () {
        document.querySelectorAll('.flying-item').forEach(el => el.remove());
        items.forEach(item => item.style.display = 'flex');
      });

      // 随机位置按钮
      randomBtn.addEventListener('click', function () {
        const containerRect = container.getBoundingClientRect();
        items.forEach(item => {
          const maxX = containerRect.width - 60;
          const maxY = containerRect.height - 60;
          const randomX = Math.floor(Math.random() * maxX);
          const randomY = Math.floor(Math.random() * maxY);
          item.style.left = `${randomX}px`;
          item.style.top = `${randomY}px`;
        });
      });

      // 创建高抛抛物线动画
      function createParabolaAnimation(startElement, endElement) {
        const flyingItem = document.createElement('div');
        flyingItem.className = 'flying-item';
        flyingItem.textContent = startElement.textContent;
        container.appendChild(flyingItem);

        const startRect = startElement.getBoundingClientRect();
        const endRect = endElement.getBoundingClientRect();
        const containerRect = container.getBoundingClientRect();

        // 转换为相对于容器的坐标
        const startX = startRect.left - containerRect.left;
        const startY = startRect.top - containerRect.top;
        const endX = endRect.left - containerRect.left;
        const endY = endRect.top - containerRect.top;

        flyingItem.style.left = `${startX + startRect.width / 2 - 15}px`;
        flyingItem.style.top = `${startY + startRect.height / 2 - 15}px`;

        // 计算控制点（增加高度参数）
        const controlX = (startX + endX) / 2;
        const controlY = Math.min(startY, endY) - parabolaHeight;

        // 动画参数
        const duration = 1000;
        const startTime = performance.now();

        function animate(currentTime) {
          const elapsed = currentTime - startTime;
          const progress = Math.min(elapsed / duration, 1);

          // 二次贝塞尔曲线计算
          const x = quadraticBezier(startX, controlX, endX, progress);
          const y = quadraticBezier(startY, controlY, endY, progress);

          flyingItem.style.left = `${x - 15}px`;
          flyingItem.style.top = `${y - 15}px`;

          if (progress < 1) {
            requestAnimationFrame(animate);
          } else {
            setTimeout(() => {
              flyingItem.remove();
            }, 300);
          }
        }

        requestAnimationFrame(animate);
      }

      // 二次贝塞尔曲线函数
      function quadraticBezier(p0, p1, p2, t) {
        return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
      }
    });
  </script>
</body>

</html>
<!-- <code_end>
  1. 添加了高度控制滑块，可实时调整抛物线高度(100-500px)
  2. 优化了容器布局和动画坐标系计算
  3. 使用requestAnimationFrame实现更流畅的动画效果
  4. 改进了元素定位和坐标转换逻辑
  5. 增加了更明显的视觉反馈和交互效果 -->